// ListCtrlFixedChecked.cpp : implementation file
//

#include "stdafx.h"
#include "ListCtrlFixedChecked.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CListCtrlFixedChecked

CListCtrlFixedChecked::CListCtrlFixedChecked(const int& iCheckedType /*=NORMAL*/, const int iKeyColumnIndex /*=0*/)
	: CListCtrlChecked(iKeyColumnIndex)
	, m_iCheckedType(iCheckedType)
{
}

CListCtrlFixedChecked::~CListCtrlFixedChecked()
{
}


BEGIN_MESSAGE_MAP(CListCtrlFixedChecked, CListCtrlChecked)
	//{{AFX_MSG_MAP(CListCtrlFixedChecked)
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
	ON_NOTIFY_REFLECT(LVN_ITEMCHANGING, OnItemchanging)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CListCtrlFixedChecked message handlers

void CListCtrlFixedChecked::PreSubclassWindow() 
{
	CListCtrlChecked::PreSubclassWindow();
}

void CListCtrlFixedChecked::SetFixed(const CString &strFixedKeys)
{
	if (strFixedKeys.IsEmpty())
		return;

	CStringItemsArray arrFixedKeys(strFixedKeys);
	for (int i= 0; i < arrFixedKeys.GetSize(); i++)
	{
		m_mapFixedKeys[arrFixedKeys[i]] = CString();
	}

	if (FIXED_BE_CHECKED & m_iCheckedType)
		SetCheckeds( strFixedKeys, DONT_RECORD_CHANGE );
}

void CListCtrlFixedChecked::OnCustomDraw(NMHDR *pNmHdr, LRESULT *pResult)
{
	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNmHdr );

	*pResult = CDRF_DODEFAULT;

	if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
	{
		*pResult = CDRF_NOTIFYITEMDRAW;
	}
	else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
	{
		*pResult = CDRF_NOTIFYSUBITEMDRAW;
	}
	else if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage )
	{
		CString & strKeyColName= GetItemText( pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem );
			CString strIdle;
		if ((TRUE == m_mapFixedKeys.Lookup( strKeyColName, strIdle ))
		 && (FALSE == m_mapRecordedCheckedKeys.Lookup( strKeyColName, strIdle )))
		{
// suspend: Gray item			pLVCD->nmcd.uItemState |= CDIS_GRAYED |CDIS_DISABLED;
			pLVCD->clrText = RGB( 185, 185, 185 );
		}
	}
}

// void CListCtrlFixedChecked::OnItemchanging(NMHDR* pNMHDR, LRESULT* pResult) 
// {
// 	NM_LISTVIEW* pNMListView = reinterpret_cast<NMLISTVIEW*>(pNMHDR);
// 
// 		CString strIdle;
// 	if ((-1 != pNMListView->iItem)
// 	 && (RECORD_CHANGE == m_ifRecordStatesChange))
// 	{
// 		if (DOUBLE_CHECK & m_iCheckedType)
// 		{
// 			if ((2 == ((LVIS_STATEIMAGEMASK & pNMListView->uOldState) >> 12))
// 			 && (1 == ((LVIS_STATEIMAGEMASK & pNMListView->uNewState) >> 12)))	// Unchecked
// 			{
// 				const CString &strItemKey= GetItemText( pNMListView->iItem, m_iKeyCol );
// 					CString strIdle;
// 				if (TRUE == m_mapRecordedCheckedKeys.Lookup( strItemKey, strIdle ))
// 				{
// 					if ((FIXED_BE_CHECKED & m_iCheckedType)
// 					 && (TRUE == m_mapFixedKeys.Lookup( strItemKey, strIdle )))
// 					{
// 						LVITEM lvi;
// 							lvi.stateMask = LVIS_STATEIMAGEMASK |LVIF_PARAM;
// 							lvi.state = INDEXTOSTATEIMAGEMASK( 1 );
// 							lvi.lParam = m_ifRecordStatesChange;
// ASSERT(::IsWindow(m_hWnd));
// 						::PostMessage( m_hWnd, LVM_SETITEMSTATE, pNMListView->iItem, (LPARAM)&lvi );
// 					}
// 					*pResult = 0;
// 					return;
// 				} 
// 				else
// 				{
// 					m_mapRecordedCheckedKeys[strItemKey] = CString();
// 					RedrawItems( pNMListView->iItem, pNMListView->iItem );
// 					*pResult = TRUE;
// 					return;
// 				}
// 			}
// 		}
// 		else // if ((FALSE == (DOUBLE_CHECK & m_iCheckedType))
// 		{
// 			if (TRUE == m_mapFixedKeys.Lookup( GetItemText( pNMListView->iItem, m_iKeyCol ), strIdle ))
// 			{
// 				*pResult = TRUE;
// 				return;
// 			}
// 		}
// 	}
// 
// 	*pResult = 0;
// }

void CListCtrlFixedChecked::OnItemchanging(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = reinterpret_cast<NMLISTVIEW*>(pNMHDR);

	if (RECORD_CHANGE == m_ifRecordStatesChange)
	{
			CString strIdle;
		const CString &strItemKey= GetItemText( pNMListView->iItem, m_iKeyCol );
		if ((-1 != pNMListView->iItem)
		 && (LVIF_STATE & pNMListView->uChanged)
		 && (TRUE == m_mapFixedKeys.Lookup( strItemKey, strIdle )))
		{
			if (DOUBLE_CHECK & m_iCheckedType)
			{
				int iNewState= (LVIS_STATEIMAGEMASK & pNMListView->uNewState) >> 12;
				int iOldState= (LVIS_STATEIMAGEMASK & pNMListView->uOldState) >> 12;
				if (2 == iNewState)		// Checking
				{
					if (2 == iOldState)
					{
						m_mapRecordedCheckedKeys[strItemKey] = CString();
						RedrawItems( pNMListView->iItem, pNMListView->iItem );
					}
					*pResult = 0;
					return;
				}
				else if (1 == iNewState)// Unchecking
				{
					if (TRUE == m_mapRecordedCheckedKeys.Lookup( strItemKey, strIdle ))
					{
ASSERT(TRUE==			m_mapRecordedCheckedKeys.RemoveKey( strItemKey )	);
						RedrawItems( pNMListView->iItem, pNMListView->iItem );
					}
					else
					{
						m_mapRecordedCheckedKeys[strItemKey] = CString();
						RedrawItems( pNMListView->iItem, pNMListView->iItem );
					}

					*pResult = TRUE;
					return;
				}
			}
			else // if ((FALSE == (DOUBLE_CHECK & m_iCheckedType))
			{
				*pResult = TRUE;
				return;
			}
		}
	}

	*pResult = 0;
}
